// #pragma once
// #include <pthread.h>
// #include <string>
// #include <functional>

// template<class T>
// using func_t = std::function<void(T&)>;

// template<class T>
// class Thread             //没要threadname
// {
// public:
//     Thread(func_t<T> func, T& data)
//     :_tid(0), _func(func), _data(data), _isrunning(false);
//     {}
//     static void* ThreadRoutine(void* args)
//     {
//         Thread* thread = static_cast<Thread*>(args);
//         thread->_func(thread->_data);

//         return nullptr; //迎合返回值
//     }
//     void Start()
//     {
//         int n = pthread_create(&tid, nullptr, ThreadRoutine, this);

//         if(n == 0) //创建成功
//             _isrunning = true;
//     }
//     void Join()
//     {
//         if(!_isrunning) return;
//         int n = pthread_join(_tid, nullptr);

//         if(n == 0) //等待成功
//             _isrunning = false;
//     }
// private:
//     int _tid;
//     func_t<T> _func;
//     T _data;
//     bool _isrunning;
// };

#pragma once
#include <pthread.h>
#include <functional>
#include <string>

template<class T>
using func_t = std::function<void(T&)>;

template<class T>
class Thread
{
public:
    Thread(const std::string& threadname, func_t<T> func, const T& data)
    :_threadname(threadname), _func(func), _data(data), _isrunning(false)
    {}

    static void* ThreadRoutine(void* args)
    {
        Thread* thread = static_cast<Thread*>(args);
        thread->_func(thread->_data);       //直接_data为什么不行 ,因为他是static所以取不到_data
        return nullptr;
    }
    
    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this); //注意传this
        if(n == 0)
        {
            _isrunning = true;
            return true;
        }
        else return false;
    }
    bool Join()
    {
        if(!_isrunning) return false;
        int n = pthread_join(_tid, nullptr);    
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        else return false;
    }
    std::string ThreadName()
    {
        return _threadname;
    }
    ~Thread()
    {}
private:
    pthread_t _tid;
    std::string _threadname;
    func_t<T> _func;
    T _data;
    
    bool _isrunning;
};